home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_13_01
/
kuzdrall
/
longtxf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-06
|
4KB
|
116 lines
/* ***< LNGTXF.CEE >*** */
/* Copyright 1994 James A. Kuzdrall
Free license to this software is granted only if the above
copyright credit is included in the source code */
/* put system headers here */
#include <stdio.h> /* usual definitions */
/* use limit if does not exceed range of host machine */
#define MAXLNG 2147483647L /* limit +2147483647 */
#define MINLNG -2147483648L /* limit -2147483648 */
#define XFER_ERROR -1 /* a non-zero integer */
/***< fputl >*** ++++++++++++++++++++++++++++++++++++++++++++++ *
USE....... Convert host's long integer to the 4-byte, 2's comple-
ment, MSB-first standard transfer format. Send the four bytes
to the output stream fp.
RETURNS... Non-zero if error; otherwise, 0
No number sent if error.
ERRORS.... Disk errors of putc().
Overrange if exceeds transfer range, 2147483647 to -2147483648.
*/
int fputl(lp,fp)
long *lp; /* long to put on disk */
FILE *fp; /* file pointer given by fopen() */
{
int ix; /* byte counter */
long absl; /* absolute value of *lp */
unsigned int byt[5]; /* byt[0] is most significant */
int err;
if( MINLNG != -2147483647 && *lp == MINLNG ) {
byt[0]= 0x80; /* set 2's complement -2147483648 */
byt[1]= byt[2]= byt[3]= 0;
}
else {
/* avoid problem with -MINLNG in 2's comp, 4-byte */
absl= (*lp <= -1L && *lp >= -2147483647) ? -*lp : *lp;
/* divide magnitude into bytes; if neg, negate in 2's comp */
byt[4]= 0x100; /* becomes 1 after >> 8 */
for( ix= 3; ix >= 0; ix-- ) { /* process from LSB to MSB */
byt[ix]= (absl >> (8*(3-ix))) & 0xff;
if( *lp <= -1L )
byt[ix]= (byt[ix] ^ 0xff) + (byt[ix+1] >> 8);
}
}
err= XFER_ERROR; /* preset */
/* if in range, send MSB first */
if( *lp <= MAXLNG && (*lp >= -2147483647 || *lp == MINLNG) ) {
for( ix= 0; ix < 4; ix++ )
if( putc(byt[ix],fp) == EOF )
goto plxit;
err= 0;
}
plxit:
return( err );
}
/***< fgetl >*** ++++++++++++++++++++++++++++++++++++++++++++++ *
USE....... Read a standard format, 4-byte long integer from the
input stream fp and convert it to the host's long format.
RETURNS... ERROR if error; otherwise, 0
Places answer at pointer if no errors.
ERRORS.... From getc() only; generates no errors of its own.
*/
int fgetl(lp,fp)
long *lp; /* place where answer goes */
FILE *fp; /* file pointer given by fopen() */
{
int ix; /* byte counter */
char neg; /* non-zero (true) if original nr was negative */
long ans; /* temporary */
unsigned int byt[5]; /* byt[0] is most significant */
int err;
err= XFER_ERROR; /* preset */
for( ix= 0; ix<4; ix++ ) { /* byte read from MSB to LSB */
if( (byt[ix]= getc(fp)) == EOF )
goto glxit;
byt[ix] &= 0xff; /* remove any high bits */
}
/* detect special case, -2147483648 in non-2's complement host */
if( MINLNG == -2147483647 && byt[0] == 0x80 && !byt[1] &&
!byt[2] && !byt[3] )
goto glxit; /* out-of-range error */
err= 0; /* no error */
ans= 0L;
byt[4]= 0x100; /* becomes 1 after >> 8 */
neg= byt[0] & 0x80;
for( ix= 3; ix >= 0; ix-- ) {
if( neg ) /* make negative nrs positive by 2's comp negate */
byt[ix]= (byt[ix] ^ 0xff) + (byt[ix+1] >> 8);
ans |= ((long )(byt[ix] & 0xff)) << 8*(3-ix);
}
/* handle MINLNG separately; has negate and range problems */
if( byt[0] & 0x80 ) /* only MINLNG is still neg */
*lp= MINLNG;
else /* for all but MINLNG */
*lp= neg ? -ans : ans; /* let host install sign */
glxit:
return( err );
}